package com.szl.group.config.auth;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.szl.group.config.auth.custom.CustomUserDetails;
import com.szl.group.entity.SysUserDO;
import com.szl.group.mapper.SysUserMapper;
import com.szl.group.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * description: 框架需要使用到一个实现了UserDetailsService接口的类
 * author: shenxiaolong
 * date: 2020/6/21  16:57
 */
@Service
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private ISysUserService sysUserService;

    @Resource
    private SysUserMapper sysUserMapper;

    @Transactional
    public List<SysUserDO> getAllUser() {
        return sysUserService.list();
    }

    @Transactional
    public SysUserDO getByUsername(String username) {
        QueryWrapper<SysUserDO> qu = new QueryWrapper<>();
        return sysUserService.getOne(qu.eq("username", username));
    }

    @Override
    //重写UserDetailsService接口里面的抽象方法
    //根据用户名 返回一个UserDetails的实现类的实例
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        System.out.println("查找用户：" + username);
        //加载基础用户信息
        CustomUserDetails userDetails = sysUserMapper.findByUserName(username);

        Optional.ofNullable(userDetails).orElseThrow(()-> new BadCredentialsException("用户名不存在！"));

        //加载用户角色列表
        List<String> roleCodes = sysUserMapper.findRoleByUserName(username);

        //通过用户角色列表加载用户的资源权限列表
        List<String> authorities = sysUserMapper.findAuthorityByRoleCodes(roleCodes);

        //角色是一个特殊的权限，ROLE_前缀
        roleCodes = roleCodes.stream()
                .map(rc -> "ROLE_" + rc)
                .collect(Collectors.toList());

        authorities.addAll(roleCodes);

        userDetails.setAuthorities(
                AuthorityUtils.commaSeparatedStringToAuthorityList(
                        String.join(",", authorities)
                )
        );

        return userDetails;
    }
}
